﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Helpers;
using System.Web.Mvc;
using Epam.PeopleInterfaces;
using Epam.PeopleModel;
using PeopleListTask.Validators;

namespace PeopleListTask.CustomDataBinders
{
    public class JsonPeopleCollectionBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            controllerContext.HttpContext.Request.InputStream.Position = 0;
            string collection= new StreamReader(controllerContext.HttpContext.Request.InputStream).ReadToEnd();
            var root = Json.Decode(collection);
            var obj=root.Root;
            var entities=new List<IPeopleEntity>();
            if (obj.Id == null)
                obj.Id = Guid.NewGuid().ToString();
            if (obj.Name == null)
            {
                foreach (var item in obj)
                {
                    entities.Add(CreateEntity(item, bindingContext));
                }
            }
            else
                entities.Add(CreateEntity(obj, bindingContext));
            return entities;
        }

        protected bool FirstStepValidate(out Guid id, out string name, out DateTime date, out double weight, out double height, dynamic item, ModelBindingContext bindingContext)
        {
            bool result=true;
            name = item.Name;
            weight = 0;
            height = 0;
            if(!Guid.TryParse(item.Id,out id))
            {
                bindingContext.ModelState.AddModelError("Id","Invalid model");
                result = false;
            }
            if(!DateTime.TryParse(item.BirthDate,out date))
            {
                bindingContext.ModelState.AddModelError("BirthDate", "Invalid date of birth");
                result = false;
            }
            if (item.Weight is double || item.Weight is int) weight = item.Weight;
            else
            {
                bindingContext.ModelState.AddModelError("Weight", "Invalid weight parameter");
                result = false;
            }
            if (item.Height is double || item.Height is int) height = item.Height;
            else
            {
                bindingContext.ModelState.AddModelError("Height", "Invalid height parameter");
                result = false;
            }
            return result;
        }

        protected PeopleEntity CreateEntity(dynamic item,ModelBindingContext bindingContext)
        {
            Guid newid;
            string newname;
            DateTime newdate;
            double newweight;
            double newheight;
            PeopleEntity newentity = !FirstStepValidate(out newid, out newname, out newdate, out newweight, out newheight, item,
                                                        bindingContext) ? new PeopleEntity() : new PeopleEntity(newid, newname, newdate, newheight, newheight);
            PeopleValidators.ValidateName(newentity, bindingContext);
            PeopleValidators.ValidateDate(newentity, bindingContext);
            PeopleValidators.ValidateWeight(newentity, bindingContext);
            PeopleValidators.ValidateHeight(newentity, bindingContext);
            return newentity;
        }
    }
}